﻿#include "ucommonbutton.h"
#include "style/ustylepainter.h"
#include "style/upalette.h"
#include "uapplication.h"

class UCommonButtonPrivate
{
public:
    UCommonButtonPrivate(UCommonButton* q) : q_ptr(q) {}
    ~UCommonButtonPrivate() {}

    void init();

    void initColor(UCommonButtonOption* option) const;

private:
    Q_DECLARE_PUBLIC(UCommonButton)
    Q_DISABLE_COPY(UCommonButtonPrivate)
    UCommonButton* const q_ptr = nullptr;

    int radius = 0;
    RadiuPosition position = All;
    int backgroundRole = QPalette::Button;
    int foregroundRole = QPalette::ButtonText;
    UCommonButtonOption::ButtonFeature feature = UCommonButtonOption::DeepButton;
    Qt::Alignment alignment = Qt::AlignCenter;
};

void UCommonButtonPrivate::init()
{
}

void UCommonButtonPrivate::initColor(UCommonButtonOption* option) const
{
    Q_Q(const UCommonButton);
    UPalette* palette = uApp->applicationPalette();
    QPalette::ColorGroup cg = UProxyStyle::colorGroup(option, q);
    QColor textColor = palette->color(cg, foregroundRole);
    QColor backgroundColor = Qt::transparent;
    QColor penColor = Qt::transparent;
    if (option->features & UCommonButtonOption::DeepButton)
    {
        textColor = palette->color(cg, QPalette::HighlightedText);
        backgroundColor = palette->color(cg, backgroundRole);
        if (option->state & QStyle::State_Enabled)
        {
            if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On)
            {
                backgroundColor = backgroundColor.darker(130);
            }
            else if (option->state & QStyle::State_MouseOver)
            {
                backgroundColor = backgroundColor.darker(110);
            }
        }
    }

    if (option->features & UCommonButtonOption::LightButton)
    {
        backgroundColor = palette->color(cg, backgroundRole);
        backgroundColor.setAlphaF(0.2);
        penColor = palette->color(cg, foregroundRole);
        if (option->state & QStyle::State_Enabled)
        {
            if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On)
            {
                textColor = palette->color(cg, QPalette::HighlightedText);
                backgroundColor = palette->color(cg, backgroundRole).darker(130);
                penColor = backgroundColor;
            }
            else if (option->state & QStyle::State_MouseOver)
            {
                textColor = palette->color(cg, QPalette::HighlightedText);
                backgroundColor = palette->color(cg, backgroundRole);
                penColor = backgroundColor;
            }
        }
    }

    if (option->features & UCommonButtonOption::PlainButton)
    {
        textColor = palette->color(cg, QPalette::ButtonText);
        penColor = textColor;
        auto color = palette->color(cg, backgroundRole);
        color.setAlphaF(0.2);
        if (option->state & QStyle::State_Enabled)
        {
            if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On)
            {
                textColor = palette->color(cg, foregroundRole).darker(130);
                penColor = palette->color(cg, backgroundRole).darker(130);
                backgroundColor = color;
            }
            else if (option->state & QStyle::State_MouseOver)
            {
                textColor = palette->color(cg, foregroundRole);
                penColor = palette->color(cg, backgroundRole);
                backgroundColor = color;
            }
        }
    }

    if (option->features & UCommonButtonOption::UCommandLinkButton)
    {
        if (option->state & QStyle::State_Enabled)
        {
            if (option->state & QStyle::State_Sunken || option->state & QStyle::State_On)
            {
                textColor = textColor.darker(130);
            }
            else if (option->state & QStyle::State_MouseOver)
            {
                textColor = textColor.darker(110);
            }
        }
    }

    option->backgroundColor = backgroundColor;
    option->foregroundColor = textColor;
    option->borderColor = penColor;
}

UCommonButton::UCommonButton(const QString text, QWidget* parent) : QPushButton(text, parent)
    , d_ptr(new UCommonButtonPrivate(this))
{
    Q_D(UCommonButton);
    d->init();
}

UCommonButton::UCommonButton(QWidget* parent) : QPushButton(parent)
    , d_ptr(new UCommonButtonPrivate(this))
{
    Q_D(UCommonButton);
    d->init();
}

UCommonButton::~UCommonButton()
{
}

Qt::Alignment UCommonButton::alignment() const
{
    Q_D(const UCommonButton);
    return d->alignment;
}

void UCommonButton::setAlignment(Qt::Alignment alignment)
{
    Q_D(UCommonButton);
    if (d->alignment != alignment)
    {
        d->alignment = alignment;
        update();
    }
}

void UCommonButton::setButtonFeature(UCommonButtonOption::ButtonFeature feature)
{
    Q_D(UCommonButton);
    if (d->feature != feature)
    {
        d->feature = feature;
        update();
    }
}

void UCommonButton::setRadius(int radius)
{
    Q_D(UCommonButton);
    if (d->radius != radius)
    {
        d->radius = radius;
        update();
    }
}

void UCommonButton::setBackgroundRole(int role)
{
    Q_D(UCommonButton);
    if (d->backgroundRole != role)
    {
        d->backgroundRole = role;
        update();
    }
}

void UCommonButton::setForegroundRole(int role)
{
    Q_D(UCommonButton);
    if (d->foregroundRole != role)
    {
        d->foregroundRole = role;
        update();
    }
}

void UCommonButton::setRadiuPosition(RadiuPosition position)
{
    Q_D(UCommonButton);
    if (d->position != position)
    {
        d->position = position;
        update();
    }
}

void UCommonButton::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event)

    UCommonButtonOption btn;
    initStyleOption(&btn);
    UStylePainter stylePainter(this);
    stylePainter.drawControl(UProxyStyle::CE_UCommonButton, btn);
}

void UCommonButton::initStyleOption(UCommonButtonOption* option) const
{
    Q_D(const UCommonButton);
    QPushButton::initStyleOption(option);

    option->radius = d->radius;
    option->position = d->position;
    option->features |= UCommonButtonOption::ButtonFeatures(d->feature);
    option->alignment = d->alignment;
    d->initColor(option);
}
